package src

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"net/http"
	"reflect"
)

type Predicates struct {
	Header HeaderPredicate
	Method string
	Host   string
	Path   PathPredicate
}

type Route struct {
	Id           string
	Url          string
	Predicates   Predicates
	Filters      []interface{}
	orderFilters []interface{}
}

type Routes []*Route

type RoutesConfig struct {
	Routes Routes
}

// 获取配置参数
func InitConfig() Routes {
	gatewayData, err := ioutil.ReadFile("gateway.yaml")
	if err != nil {
		log.Fatalln("读取配置文件失败", err)
	}
	routeConfig := RoutesConfig{}
	err = yaml.Unmarshal(gatewayData, &routeConfig)
	if err != nil {
		log.Fatalln("配置文件解析失败", err)
	}
	fmt.Println(routeConfig.Routes[0].Filters)
	return routeConfig.Routes
}

// 判断路由path是否匹配
func (routes Routes) Match(request *http.Request) *Route {
	for _, r := range routes {
		if isMatch(r, request) {
			return r
		}
	}
	return nil
}

func isMatch(r *Route, request *http.Request) bool {
	// 这里可以用反射，如果实现了PredicateMatcher中的Match接口
	//if r.Predicates.Path.Match(request) == false {
	//	return false
	//}
	//if r.Predicates.Header.Match(request) == false {
	//	return false
	//}
	// 通过反射机制，来判断Predict中的字段是否都实现了PredicateMatcher接口
	v := reflect.ValueOf(r.Predicates)
	for i := 0; i < v.NumField(); i++ {
		if match, ok := v.Field(i).Interface().(PredicateMatcher); ok {
			if !match.Match(request) {
				return false
			}
		}
	}
	return true
}
